﻿using CATLTempUpdate.CommonLib;
using CATLTempUpdate.TcpClient;
using CATLTempUpdate.TcpServer;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
using System.Timers;
using System.Windows.Forms;

namespace CATLTempUpdate
{
    class TcpReciveAndSend
    {
        string SecServerIP = "127.0.0.1";
        string ServiceIP = "172.20.2.140";
        //string ServiceIP = "192.168.1.249";
        int MTPort = 8087;   //
        int SecPort = 6000;   //
        public static bool exit = false;
        TcpServer.SocketManager SecDataSocket;      //应答SEC请求的服务器

        public TcpServer.SocketManager TempStockingSocket;                  //此服务端用于解析温度采集终端的数据


        //<summary>  
        //内存回收定时器  
        //</summary>  
        System.Timers.Timer GCCollectTimer = null;


        public AnalysisBytes TempStockingAnalysis = new AnalysisBytes();        //温度采集解析
        public AnalysisBytes AnalysisSecData = new AnalysisBytes();             //Sec应答报文解析


        public TcpReciveAndSend()
        {
            InitTempStockingSocket();       //初始化温度采集服务端
            //InitSecReplySocket();           //初始化Sec数据请求服务端
            GCCollect();
        }

        /// <summary>
        /// 初始化温度采集服务端的Server
        /// </summary>
        private void InitTempStockingSocket()
        {
            //此服务端用于采集温度板子数据
            TempStockingSocket = new TcpServer.SocketManager(100, 10240);//sec的数据接口（10000）连接
            TempStockingSocket.Init();
            TempStockingSocket.Start(new IPEndPoint(IPAddress.Parse(ServiceIP), MTPort));
            TempStockingSocket.ReceiveClientData += new TcpServer.SocketManager.OnReceiveData(ReciveTempData);
            //开始发送sndlist里的data
            Thread sendReplyTempMTdata = new Thread(SendTempPackData);
            sendReplyTempMTdata.Start();

            //开始发送sndlist里的data
            Thread alivethread = new Thread(SendAliveData);
            alivethread.Start();
        }


        /// <summary>
        /// 初始化Sec温度数据应答服务端的Server
        /// </summary>
        private void InitSecReplySocket()
        {
            //此服务端用于采集温度板子数据
            SecDataSocket = new TcpServer.SocketManager(100, 10240);//sec的数据接口（10000）连接
            SecDataSocket.Init();
            SecDataSocket.Start(new IPEndPoint(IPAddress.Parse(SecServerIP), SecPort));
            SecDataSocket.ReceiveClientData += new TcpServer.SocketManager.OnReceiveData(ReciveDataFromSec);
            //开始发送sndlist里的data
            Thread sendReplySecThread = new Thread(SendReplySECData);
            sendReplySecThread.Start();
        }



        /// <summary>
        /// 发送心跳包
        /// </summary>
        public void SendAliveData()
        {
            string AlivePack = "7E 01 FF FF 0F 00 02 00 00 5F 0C 7E";
            byte[] Temparray = strToToHexByte(AlivePack);
            while (exit == false)
            {
                try
                {
                    for (int i = 0; i < TempStockingSocket.m_clients.Count; i++)
                    {
                        string IP = TempStockingSocket.m_clients[i].IPAddress.ToString();
                        if (IP.Contains("172.20.2"))
                        {
                            TempStockingSocket.SendMessage(TempStockingSocket.m_clients[i], Temparray);
                            //Log.AddLog(LogFile.SystemError, "已发送给TM" + "IP为:" + TempStockingSocket.m_clients[i].IPAddress.ToString() + "," + "：" + string.Join("-", Temparray));
                        }

                    }
                    //Log.AddLog(LogFile.SystemError, "                  ");
                    Thread.Sleep(5);
                }
                catch (Exception ex)
                {
                    Log.AddLog(LogFile.SystemError, "发送应答数据失败" + ex.ToString());
                }
                Thread.Sleep(2000);
            }
        }

        private static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }


        /// <summary>
        /// 发送应答SEC的Pack
        /// </summary>
        public void SendReplySECData()
        {
            while (exit == false)
            {
                if (AnalysisBytes.sndSECBytes.Count > 0)
                {
                    try
                    {
                        SecDataSocket.SendMessage(AnalysisBytes.sndSECBytes[0]);
                        //Thread.Sleep(100);
                        lock (AnalysisBytes.sndSECBytes)
                        {
                            AnalysisBytes.sndSECBytes.RemoveAt(0);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.AddLog(LogFile.SystemError, "发送应答数据失败" + ex.ToString());
                    }
                }
                else
                {
                    Thread.Sleep(100);
                }
            }
        }
        /// <summary>
        /// 设置温度list的index对应的温度
        /// </summary>
        /// <param name="canno">CanNo</param>
        /// <param name="colno">列号</param>
        /// <param name="rowno">层号</param>
        /// <param name="chno">通道号</param>
        /// <param name="tempdata">温度</param>
        private void SetTempData(int canno, int colno, int rowno, int chno, Byte[] tempdata)
        {
            try
            {
                if (chno <= 25)
                {
                    int startindex = 8;
                    int tempindex = 0;
                    //colno = colno % 4;
                    //rowno = rowno % 4;

                    if (colno % 4 == 0)
                    {
                        colno = 3;
                    }
                    else
                    {
                        colno = colno % 4;
                        colno = colno - 1;
                    }

                    if (rowno == 4)
                    {
                        rowno = 0;
                    }
                    else
                    {
                        rowno = 4 - rowno;
                    }

                    int tempchno = chno;
                    //int tempchno = NewSeq[chno];
                    //tempchno=NewSeq[chno];
                    if (tempchno == 1)
                    {
                        tempchno = 0;
                    }
                    else
                    {
                        tempchno = tempchno - 1;
                    }
                    //暂时不判断24通道问题
                    tempindex = startindex + colno * 320 + rowno * 80 + 30 + tempchno * 2;
                    switch (canno)
                    {

                        case 1:
                            TempCanData.Can1Temp[tempindex] = tempdata[1];
                            TempCanData.Can1Temp[tempindex + 1] = tempdata[0];
                            break;
                        case 2:
                            TempCanData.Can2Temp[tempindex] = tempdata[1];
                            TempCanData.Can2Temp[tempindex + 1] = tempdata[0];
                            break;
                        case 3:
                            TempCanData.Can3Temp[tempindex] = tempdata[1];
                            TempCanData.Can3Temp[tempindex + 1] = tempdata[0];
                            break;
                    }
                }

            }
            catch (Exception ex)
            {

                Log.SystemError.Add(ex.ToString());
            }

        }


        //private void ReciveDataFromBCF(byte[] buff)
        //{
        //    SecDataSocket.SendMessage(buff);
        //    AnalysisBytes.AsyncFindFEDCCode(buff);
        //}


        /// <summary>
        /// 异步解析温度TM的数据
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="IP"></param>
        private void ReciveTempData(byte[] buff, string IP)
        {
            //将收到的数据解析存到list中。
            TempStockingAnalysis.AnalysisTempDataCode(buff, IP);
        }

        /// <summary>
        /// 异步解析Sec发送的请求报文
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="IP"></param>
        private void ReciveDataFromSec(byte[] buff, string IP)
        {

            //将收到的数据解析存到list中。
            AnalysisSecData.FindFEDCCode(buff);
            ReplyFEDCCode();


        }
        /// <summary>
        /// 解析收到的数据并将应答数据放到sndlist中。
        /// </summary>
        public void ReplyFEDCCode()
        {
            if (AnalysisBytes.recSECBytes.Count > 0)
            {
                int begindata = -1;
                Byte[] tempbyte = new byte[6];
                //查找fe 和dc 即 254，220

                while (AnalysisBytes.recSECBytes.Count >= 6)
                {

                    begindata = AnalysisBytes.recSECBytes.IndexOf(254);
                    AnalysisBytes.recSECBytes.RemoveRange(0, begindata);

                    //判断剩下的长度是否大于请求报文长度，并且后一位是否是dc。
                    if (AnalysisBytes.recSECBytes.Count >= 6 && AnalysisBytes.recSECBytes[1] == 220)
                    {
                        //将文件Copy到临时数组里
                        Buffer.BlockCopy(AnalysisBytes.recSECBytes.ToArray(), 0, tempbyte, 0, 6);
                        //解析tempbyte数组，查看请求的CanNo，应答对应的温度数据
                        int CanNo = tempbyte[4];
                        switch (CanNo)
                        {
                            case 1:
                                AnalysisBytes.sndSECBytes.Add(TempCanData.Can1Temp.ToArray());
                                break;
                            case 2:
                                AnalysisBytes.sndSECBytes.Add(TempCanData.Can2Temp.ToArray());
                                break;
                            case 3:
                                AnalysisBytes.sndSECBytes.Add(TempCanData.Can3Temp.ToArray());
                                break;
                            case 4:
                                AnalysisBytes.sndSECBytes.Add(TempCanData.Can4Temp.ToArray());
                                break;
                            case 5:
                                AnalysisBytes.sndSECBytes.Add(TempCanData.Can5Temp.ToArray());
                                break;
                        }
                        AnalysisBytes.recSECBytes.RemoveRange(0, AnalysisBytes.recSECBytes.Count);
                    }
                    else if (begindata > 0)
                    {
                        AnalysisBytes.recSECBytes.RemoveRange(0, begindata);
                    }
                    else
                    {
                        AnalysisBytes.recSECBytes.RemoveRange(0, AnalysisBytes.recSECBytes.Count);
                    }
                }

            }

        }

        /// <summary>
        /// 发送应答SEC的Pack
        /// </summary>
        public void SendTempPackData()
        {
            while (exit == false)
            {
                if (AnalysisBytes.sndTempMTBytes.Count > 0)
                {
                    try
                    {
                        if (exit)
                        {
                            break;
                        }
                        for (int i = 0; i < TempStockingSocket.m_clients.Count; i++)
                        {
                            TempStockingSocket.SendMessage(TempStockingSocket.m_clients[i], AnalysisBytes.sndTempMTBytes[0]);
                        }
                        //TempStockingSocket.SendMessage(AnalysisBytes.sndTempMTBytes[0]);
                        Log.AddLog(LogFile.SystemError, "已发送给TM：" + string.Join("-", AnalysisBytes.sndTempMTBytes[0]));
                        Thread.Sleep(5);
                        lock (AnalysisBytes.sndTempMTBytes)
                        {
                            AnalysisBytes.sndTempMTBytes.RemoveAt(0);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.AddLog(LogFile.SystemError, "发送应答数据失败" + ex.ToString());
                    }
                }
                else
                {
                    Thread.Sleep(100);
                }

            }


        }

        public void Dispose()
        {
            TempStockingAnalysis.Dispose();
        }




        #region 心跳包
        //心跳包也是很重要的,看自己的需要了, 我只定义出来, 你自己找个地方去调用吧  
        /// <summary>  
        /// 开启心跳  
        /// </summary>  
        private void GCCollect()
        {
            if (GCCollectTimer == null)
            {
                GCCollectTimer = new System.Timers.Timer();
                GCCollectTimer.Elapsed += TimeElapsed;
            }
            if (!GCCollectTimer.Enabled)
            {
                GCCollectTimer.AutoReset = true;     //循环执行  
                GCCollectTimer.Interval = 10000; //每10s执行一次  
                GCCollectTimer.Enabled = true;
                GCCollectTimer.Start();
            }
        }

        /// <summary>  
        /// 定时执行  
        /// </summary>  
        /// <param name="source"></param>  
        /// <param name="e"></param>  
        private void TimeElapsed(object source, ElapsedEventArgs e)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        #endregion
    }
}
